/*
 * Copyright 2008 Lucas Tan.
 * This copyright notice must always remain intact whenever you use or distribute 
 * the source code contained in this file.
 * Any usage of any code in this file, either in derived work or
 * through the use of external linkage,
 * must always be credited with the author's name.
 * 
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 * DEALINGS IN THE SOFTWARE.
 * 
 * */
using System;
using System.Collections.Generic;
using System.Text;
using Crypto = System.Security.Cryptography;

namespace PassKeeper.Cryptography
{
	public sealed class SHA512ManagedHasher : SHA512Hasher
	{
		private readonly Crypto.SHA512Managed _sha512;
	
		public SHA512ManagedHasher()
			:base()
		{
			//WARNING: the base constructor SHA512Managed() may throw an InvalidOpExcep
			// see the documentation for more info.
			//Consider implementing SHA512 ourselves.
			_sha512 = new Crypto.SHA512Managed();

			this.Initialize();
		}

		protected override void HashCore(byte[] array, int ibStart, int cbSize)
		{
			
			_sha512.TransformBlock(array, ibStart, cbSize, null, 0);
		}

		protected override byte[] HashFinal()
		{
		
			_sha512.TransformFinalBlock(new byte[] {/*This element is important though unused,
													 just in case the underlying code access this 
													 array.*/ 0 }, 0, 0);

			return _sha512.Hash;
		}

		public override void Initialize()
		{
			_sha512.Initialize();
		}

		protected override void Dispose(bool disposing)
		{
			try
			{
				if (disposing)
				{
					((IDisposable) _sha512).Dispose();
				}
			}
			finally
			{
				base.Dispose(disposing);
			}
		}
	}
}
